package main

import "fmt"

// golang 中 如果
// 标识符 首字母为大写 则对外部包可见(类似 java 中 的 public)
// 反之不可见(类似 java 中的 private)

// Person 人
type Person struct {
	name string
	age  int
}

// 作用于 特定类型 的 函数
// 接收者 表示的是 特定的类型变量, 常用类型首字母小写表示 不建议使用 this 或 self
// func (接收者变量 接收者类型) 方法名(参数...) (返回值...) { ... }

func (p Person) Say() {
	fmt.Printf("%s: My name is %s, %d years old\n", p.name, p.name, p.age)
}

// AddAge
// 值接收者 传递的是 拷贝 的 值对象
func (p Person) AddAge() {
	p.age++
}

// AddAge2
// 指针接收者 传递的是 对象 的 内存地址
// 使用场景:
// 	需要修改接收者中的值
// 	接收者是拷贝代价比较大的大对象
//	保证一致性, 如果某个方法使用了指针接收者 那么其他的方法也应该使用指针接收者
func (p *Person) AddAge2() {
	// 原始写法
	//(*p).age++

	// 语法糖
	p.age++
}

func NewPerson(name string, age int) *Person {
	return &Person{
		name,
		age,
	}
}

func main() {
	p1 := NewPerson("张三", 20)
	p1.Say()

	fmt.Println("=========================================================")

	p1.AddAge()
	p1.Say()

	fmt.Println("=========================================================")

	p1.AddAge2()
	p1.Say()
}
